Skip to content

Feature:SlangFilter 추가 닉네임에 욕설 유무 포함#208

Merged
KII1ua merged 31 commits into
developfrom
feature/slangcheck
Jun 4, 2026
Merged

Feature:SlangFilter 추가 닉네임에 욕설 유무 포함#208
KII1ua merged 31 commits into
developfrom
feature/slangcheck

Conversation

@KII1ua

@KII1ua KII1ua commented Jun 2, 2026

Copy link
Copy Markdown
Member

📌 관련 이슈

  • closes #

🔍 작업 내용

입력된 단어에 욕설데이터를 불러와 일치하는지 확인하는 유틸 클래스 생성
UserService 욕설 체크 메서드 추가
UserController 욕설 체크 엔드포인트 추가

📝 변경 사항

💬 리뷰어에게

Summary by CodeRabbit

  • 새로운 기능

    • 닉네임 금칙어(슬랭) 검사 기능을 추가해 닉네임 사용 가능 여부를 미리 확인할 수 있습니다.
    • 개인화된 AI 인사이트가 투표 결과에 제공됩니다(사용자/선택 기준).
    • 몰입형 투표용 “다음 랜덤” 조회 API를 추가했습니다.
    • 이미지 업로드로 투표를 생성할 수 있는 멀티파트 엔드포인트를 추가했습니다.
  • 개선

    • 투표 상세/피드에 댓글 수가 반영되며 이미지 URL이 없으면 썸네일로 대체됩니다.
    • 채팅 목록 정렬 및 선택 옵션 표시가 비선택 시 null 허용으로 안정화되었습니다.

@KII1ua KII1ua self-assigned this Jun 2, 2026
@coderabbitai

coderabbitai Bot commented Jun 2, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 8e718363-fbaa-40de-b10c-385b838f09a7

📥 Commits

Reviewing files that changed from the base of the PR and between c8dc491 and 6171e0b.

📒 Files selected for processing (48)
  • build.gradle.kts
  • buildSrc/src/main/kotlin/Dependencies.kt
  • scripts/deploy.sh
  • scripts/qa-seed.sql
  • src/integrationTest/java/com/ject/vs/ai/port/PersonalizedAiInsightIntegrationTest.java
  • src/integrationTest/java/com/ject/vs/user/port/UserServiceIntegrationTest.java
  • src/integrationTest/java/com/ject/vs/vote/adapter/web/VoteApiIntegrationTest.java
  • src/integrationTest/java/com/ject/vs/vote/domain/VoteRepositoryIntegrationTest.java
  • src/main/java/com/ject/vs/ai/config/GeminiProperties.java
  • src/main/java/com/ject/vs/ai/port/AiInsightService.java
  • src/main/java/com/ject/vs/ai/port/PersonalizedAiInsightService.java
  • src/main/java/com/ject/vs/ai/port/PersonalizedInsightDataCollector.java
  • src/main/java/com/ject/vs/ai/port/in/AiInsightUseCase.java
  • src/main/java/com/ject/vs/chat/adapter/event/ChatMessageEventListener.java
  • src/main/java/com/ject/vs/chat/port/ChatService.java
  • src/main/java/com/ject/vs/config/CacheConfig.java
  • src/main/java/com/ject/vs/config/OpenApiConfig.java
  • src/main/java/com/ject/vs/user/domain/User.java
  • src/main/java/com/ject/vs/user/exception/UserErrorCode.java
  • src/main/java/com/ject/vs/user/port/UserService.java
  • src/main/java/com/ject/vs/vote/adapter/handler/VoteAiInsightHandler.java
  • src/main/java/com/ject/vs/vote/adapter/web/ImmersiveVoteController.java
  • src/main/java/com/ject/vs/vote/adapter/web/VoteController.java
  • src/main/java/com/ject/vs/vote/adapter/web/dto/ImmersiveNextRequest.java
  • src/main/java/com/ject/vs/vote/adapter/web/dto/ImmersiveNextResponse.java
  • src/main/java/com/ject/vs/vote/domain/VoteParticipationRepository.java
  • src/main/java/com/ject/vs/vote/domain/VoteRepository.java
  • src/main/java/com/ject/vs/vote/port/ImmersiveVoteQueryService.java
  • src/main/java/com/ject/vs/vote/port/VoteCommandService.java
  • src/main/java/com/ject/vs/vote/port/VoteDetailQueryService.java
  • src/main/java/com/ject/vs/vote/port/VoteQueryService.java
  • src/main/java/com/ject/vs/vote/port/VoteResultQueryService.java
  • src/main/java/com/ject/vs/vote/port/in/ImmersiveVoteQueryUseCase.java
  • src/main/java/com/ject/vs/vote/port/in/VoteCommandUseCase.java
  • src/main/java/com/ject/vs/vote/port/in/VoteQueryUseCase.java
  • src/main/resources/application-prod.yml
  • src/main/resources/application.yml
  • src/unitTest/java/com/ject/vs/VsServerApplicationTests.java
  • src/unitTest/java/com/ject/vs/ai/port/PersonalizedAiInsightServiceTest.java
  • src/unitTest/java/com/ject/vs/ai/port/PersonalizedInsightDataCollectorTest.java
  • src/unitTest/java/com/ject/vs/chat/adapter/event/ChatMessageEventListenerTest.java
  • src/unitTest/java/com/ject/vs/chat/adapter/event/ChatWebSocketE2ETest.java
  • src/unitTest/java/com/ject/vs/chat/adapter/event/ChatWebSocketIntegrationTest.java
  • src/unitTest/java/com/ject/vs/chat/port/ChatServiceTest.java
  • src/unitTest/java/com/ject/vs/config/TestPropertiesConfig.java
  • src/unitTest/java/com/ject/vs/vote/port/ImmersiveVoteQueryServiceTest.java
  • src/unitTest/java/com/ject/vs/vote/port/VoteDetailQueryServiceTest.java
  • src/unitTest/java/com/ject/vs/vote/port/VoteResultQueryServiceTest.java

Walkthrough

닉네임 슬랭 감지, 개인화 AI 인사이트(수집·캐시·생성), 몰입형/이미지 투표 확장, 채팅 처리를 포함한 기능 추가 및 관련 설정·테스트 보강이 이루어졌습니다.

Changes

주요 기능 및 인프라 변경

Layer / File(s) Summary
KMP 슬랭 필터 유틸리티
src/main/java/com/ject/vs/util/SlangFilter.java
KMP 기반 실패 함수(buildFailure), kmpContains, containsSlang 구현으로 입력이 금칙어 목록을 포함하는지 검사합니다.
워드 서비스 슬랭 통합 및 데이터 로드
src/main/java/com/ject/vs/user/port/WordService.java, src/main/resources/data/slang.txt
WordService가 classpath:data/slang.txt(2141 라인)를 로드하고 containSlang을 SlangFilter에 위임합니다.
닉네임 검사 API 및 비즈니스 로직
src/main/java/com/ject/vs/user/port/UserService.java, src/main/java/com/ject/vs/user/adapter/web/UserController.java
UserService.checkNicknameSlang, modifyInfo 분기 추가 및 POST /api/users/nickname/slang 엔드포인트를 통해 결과를 반환합니다.
개인화 AI 인사이트: 수집기·서비스·UseCase·프롬프트
src/main/java/com/ject/vs/ai/port/PersonalizedInsightDataCollector.java, src/main/java/com/ject/vs/ai/port/PersonalizedAiInsightService.java, src/main/java/com/ject/vs/ai/port/AiInsightService.java, src/main/java/com/ject/vs/ai/port/in/AiInsightUseCase.java
투표·사용자 기반 통계 수집, PersonalizedVoteInsightRequest 생성, 캐시 키 포함 UseCase 확장, 개인화 프롬프트 생성 및 AI 호출 로직을 추가합니다.
AI 캐시 구성 및 의존성
src/main/java/com/ject/vs/config/CacheConfig.java, build.gradle.kts, buildSrc/src/main/kotlin/Dependencies.kt
Caffeine 의존성 추가 및 personalizedAiInsightCache Caffeine 빈(최대 1000, 24시간 만료)을 정의합니다.
Vote: 이미지 업로드·몰입형 다음 투표·리포지토리 확장
src/main/java/com/ject/vs/vote/adapter/web/VoteController.java, src/main/java/com/ject/vs/vote/port/VoteCommandService.java, src/main/java/com/ject/vs/vote/port/in/VoteCommandUseCase.java, src/main/java/com/ject/vs/vote/adapter/web/dto/ImmersiveNextRequest.java, src/main/java/com/ject/vs/vote/adapter/web/dto/ImmersiveNextResponse.java, src/main/java/com/ject/vs/vote/domain/VoteRepository.java, src/main/java/com/ject/vs/vote/domain/VoteParticipationRepository.java, src/main/java/com/ject/vs/vote/port/ImmersiveVoteQueryService.java
멀티파트 이미지 업로드 기반 투표 생성, Immersive 'next' API·DTO, 랜덤 조회/제외·카운트 쿼리 추가 및 참여 집계 JPQL 메서드들을 포함합니다.
Vote 결과에서 개인화 AI 연동
src/main/java/com/ject/vs/vote/port/VoteResultQueryService.java
정적 AI 인사이트 대신 PersonalizedAiInsightService.getOrGenerate를 호출해 개인화 인사이트를 제공하도록 변경했습니다.
채팅: 선택 옵션 조회·정렬 개선
src/main/java/com/ject/vs/chat/port/ChatService.java, src/main/java/com/ject/vs/chat/adapter/event/ChatMessageEventListener.java
findSelectedOptionCode(Optional) 사용으로 선택 정보 없음을 허용하고, getChatList 정렬에서 lastMessageAt nullsLast 역순 정렬을 적용했습니다.
OpenAPI 및 애플리케이션 설정
src/main/java/com/ject/vs/config/OpenApiConfig.java, src/main/resources/application-prod.yml, src/main/resources/application.yml
springdoc.server-url 주입/설정 추가, Gemini 기본 location/model 변경 및 admin.user-ids 확장(260 추가)을 반영했습니다.
배포 스크립트 및 리소스 변경
scripts/deploy.sh, scripts/qa-seed.sql
deploy.sh에 GEMINI_MODEL/GEMINI_LOCATION 환경 전달 추가, QA 시드 스크립트 전체 삭제가 포함됩니다.
테스트 및 테스트 인프라 보강
여러 src/integrationTestsrc/unitTest 파일들
다수의 통합/단위 테스트 추가·수정(이미지 서비스 목, 캐시/AI 시나리오, 몰입형/투표/채팅 검증 등)과 TestPropertiesConfig의 Mockito 목 빈 제공 변경이 포함됩니다.
레거시 핸들러 비활성화 등 기타
src/main/java/com/ject/vs/vote/adapter/handler/VoteAiInsightHandler.java, src/main/java/com/ject/vs/user/domain/User.java, src/main/java/com/ject/vs/user/exception/UserErrorCode.java
VoteAiInsightHandler를 deprecated+조건부 bean 등록, User.modifyImageColor 추가, USER_NICKNAME_DUPLICATE 에러코드 추가 등이 반영됩니다.

Estimated code review effort: 🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs:

Suggested labels:
✨feature

Suggested reviewers:

  • tlarbals824
  • Junhyukkkk

"🐰
닉네임 지키는 필터 깔고,
AI가 맞춤 인사이트 골라주네.
이미지 투표도 척척 올리고,
테스트는 단단히 준비했지,
당근처럼 깔끔히 배포하자!"

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목이 주요 변경사항인 욕설 필터링 기능 추가를 명확하게 설명하고 있으며, 변경된 파일들의 내용과 일치합니다.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/slangcheck

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions

github-actions Bot commented Jun 2, 2026

Copy link
Copy Markdown

빌드 성공
배포 준비 완료!

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/main/java/com/ject/vs/user/port/WordService.java (1)

34-43: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

로딩 실패 시 슬랭 검사가 무력화(fail-open)됩니다.

init()에서 slang.txt 로딩이 실패하면 slang은 빈 리스트로 남고, 이후 containSlang은 항상 false를 반환하여 모든 닉네임이 금칙어 검사를 통과합니다. 로그만 남기고 정상 기동되므로 운영 중 조용히 필터가 비활성화될 수 있습니다. 필수 리소스 로딩 실패 시 기동을 중단하거나 별도 헬스 지표로 노출하는 것을 검토해 주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/ject/vs/user/port/WordService.java` around lines 34 - 43,
The init() method currently swallows IOExceptions and leaves the slang list
empty so containSlang will always return false; change init() (and callers if
needed) to treat slang.txt as a required resource: when
loadWords("classpath:data/slang.txt") throws, rethrow a runtime exception or
call System.exit(1) (or set a failing health flag) so the application fails to
start (or exposes an unhealthy status) instead of continuing with an empty slang
list; ensure the change references init(), loadWords(...) and the slang field so
the service either aborts startup or flips a health indicator when slang loading
fails.
🧹 Nitpick comments (2)
src/main/java/com/ject/vs/user/adapter/web/UserController.java (1)

44-47: 💤 Low value

Swagger 문서화 누락: @Operation 추가 권장.

인접한 다른 엔드포인트들은 모두 @Operation(summary=..., description=...)을 부여하고 있으나 신규 /nickname/slang만 누락되어 API 문서에서 설명이 비게 됩니다. 일관성을 위해 추가해 주세요.

📝 제안
+    `@Operation`(summary = "닉네임 금칙어 확인", description = "닉네임에 금칙어 포함 여부를 확인합니다.")
     `@PostMapping`("/nickname/slang")
     public ResponseEntity<NicknameCheckResponse> checkNicknameSlang(`@AuthenticationPrincipal` Long userId, `@RequestBody` UserNicknameRec nickname) {
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/ject/vs/user/adapter/web/UserController.java` around lines
44 - 47, Add Swagger metadata to the checkNicknameSlang endpoint by annotating
the UserController.checkNicknameSlang method with `@Operation`(summary = "...",
description = "...") similar to adjacent endpoints; include a concise summary
like "Check nickname for slang" and a description stating the behavior (inputs:
UserNicknameRec.nickname, requires authentication, returns
NicknameCheckResponse), ensuring imports for
io.swagger.v3.oas.annotations.Operation are present if missing.
src/main/java/com/ject/vs/user/port/WordService.java (1)

84-86: 💤 Low value

메서드명 문법 제안: containSlangcontainsSlang.

3인칭 단수 형태가 자연스럽고 SlangFilter.containsSlang과도 일관됩니다. 호출부(UserService)도 함께 변경이 필요합니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/ject/vs/user/port/WordService.java` around lines 84 - 86,
Rename the method containSlang to containsSlang in WordService (change the
method declaration name from containSlang to containsSlang) and update all call
sites to use the new name (notably the UserService caller); keep the
implementation body as-is (it already delegates to SlangFilter.containsSlang),
and ensure any interfaces, overrides, and unit tests referencing containSlang
are renamed to containsSlang so the code compiles and remains consistent with
SlangFilter.containsSlang.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/main/java/com/ject/vs/util/SlangFilter.java`:
- Around line 40-48: containsSlang은 현재 입력 내부의 부분 문자열만 검사하므로 짧거나 일상어인
금칙어(slangList의 "시간","초딩","년" 등)에 대해 과도한 오탐이 발생합니다; 수정 방안으로 containsSlang과
kmpContains 호출 로직을 변경해 짧은 항목(예: 길이<=2 또는 <=3)이나 명시된 일상어 목록에 대해선 전체 단어 일치 또는 단어
경계 검사만 허용하고(예: 공백/문장부호/문자 경계 기준), 긴 항목에 대해서만 기존 부분 문자열 검색을 유지하도록 구현하세요; 이를 위해
containsSlang에서 각 slang에 대해 slang.length()를 검사하고 짧은/화이트리스트 항목은 단어 경계 검사
함수(isWordBoundaryMatch)로 처리하고 나머지는 kmpContains(text, slang.toCharArray())를 호출하도록
변경하세요.
- Line 44: SlangFilter currently iterates slangList without a null guard; add a
defensive null-check at the start of the public method in SlangFilter that uses
the slangList (e.g., if (slangList == null || slangList.isEmpty()) return
<no-op>), so the method treats a null list as empty and returns the input/result
unchanged (or false) instead of throwing NPE; update the method that contains
the for(String slang : slangList) loop to return early when slangList is null.

In `@src/main/resources/data/slang.txt`:
- Line 1: The first word contains a leading BOM (U+FEFF) so
WordService.loadWords currently yields "\uFEFF..." and String::trim doesn't
remove it; update loadWords to strip a leading BOM when reading lines (e.g.,
remove '\uFEFF' or use Character.isWhitespace check for U+FEFF) or ensure the
file is saved as BOM-free UTF-8; specifically modify WordService.loadWords to
call something like line = line.replaceFirst("^\uFEFF", "") (or equivalent)
before trimming and adding to the word list so the first forbidden word matches
correctly.

---

Outside diff comments:
In `@src/main/java/com/ject/vs/user/port/WordService.java`:
- Around line 34-43: The init() method currently swallows IOExceptions and
leaves the slang list empty so containSlang will always return false; change
init() (and callers if needed) to treat slang.txt as a required resource: when
loadWords("classpath:data/slang.txt") throws, rethrow a runtime exception or
call System.exit(1) (or set a failing health flag) so the application fails to
start (or exposes an unhealthy status) instead of continuing with an empty slang
list; ensure the change references init(), loadWords(...) and the slang field so
the service either aborts startup or flips a health indicator when slang loading
fails.

---

Nitpick comments:
In `@src/main/java/com/ject/vs/user/adapter/web/UserController.java`:
- Around line 44-47: Add Swagger metadata to the checkNicknameSlang endpoint by
annotating the UserController.checkNicknameSlang method with `@Operation`(summary
= "...", description = "...") similar to adjacent endpoints; include a concise
summary like "Check nickname for slang" and a description stating the behavior
(inputs: UserNicknameRec.nickname, requires authentication, returns
NicknameCheckResponse), ensuring imports for
io.swagger.v3.oas.annotations.Operation are present if missing.

In `@src/main/java/com/ject/vs/user/port/WordService.java`:
- Around line 84-86: Rename the method containSlang to containsSlang in
WordService (change the method declaration name from containSlang to
containsSlang) and update all call sites to use the new name (notably the
UserService caller); keep the implementation body as-is (it already delegates to
SlangFilter.containsSlang), and ensure any interfaces, overrides, and unit tests
referencing containSlang are renamed to containsSlang so the code compiles and
remains consistent with SlangFilter.containsSlang.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: c2140d02-1c26-428d-83ab-50fc806bcb4a

📥 Commits

Reviewing files that changed from the base of the PR and between 589756c and c8dc491.

📒 Files selected for processing (5)
  • src/main/java/com/ject/vs/user/adapter/web/UserController.java
  • src/main/java/com/ject/vs/user/port/UserService.java
  • src/main/java/com/ject/vs/user/port/WordService.java
  • src/main/java/com/ject/vs/util/SlangFilter.java
  • src/main/resources/data/slang.txt

Comment on lines +40 to +48
public static boolean containsSlang(String input, List<String> slangList) {
if(input == null || input.isBlank()) return false;
char[] text = input.toCharArray();

for(String slang : slangList) {
if(kmpContains(text, slang.toCharArray())) return true;
}
return false;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

부분 문자열(substring) 매칭으로 인한 과도한 오탐 위험.

containsSlang은 닉네임에 금칙어가 부분 문자열로 포함되기만 하면 매칭됩니다. 그런데 slang.txt에는 시간(Line 2134), 초딩(Line 2106), 보딩(Line 2109), (Line 1473), (Line 1474) 등 단독으로는 일상어이거나 매우 짧은 항목이 다수 포함되어 있습니다. 그 결과 시간여행자, 초딩탈출 같은 정상 닉네임이 차단되는 오탐이 광범위하게 발생합니다.

단어 경계 검사나 짧은/일상어 항목에 대한 별도 정책(완전 일치 등)을 도입하는 것을 검토해 주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/ject/vs/util/SlangFilter.java` around lines 40 - 48,
containsSlang은 현재 입력 내부의 부분 문자열만 검사하므로 짧거나 일상어인 금칙어(slangList의 "시간","초딩","년" 등)에
대해 과도한 오탐이 발생합니다; 수정 방안으로 containsSlang과 kmpContains 호출 로직을 변경해 짧은 항목(예: 길이<=2
또는 <=3)이나 명시된 일상어 목록에 대해선 전체 단어 일치 또는 단어 경계 검사만 허용하고(예: 공백/문장부호/문자 경계 기준), 긴 항목에
대해서만 기존 부분 문자열 검색을 유지하도록 구현하세요; 이를 위해 containsSlang에서 각 slang에 대해
slang.length()를 검사하고 짧은/화이트리스트 항목은 단어 경계 검사 함수(isWordBoundaryMatch)로 처리하고 나머지는
kmpContains(text, slang.toCharArray())를 호출하도록 변경하세요.

if(input == null || input.isBlank()) return false;
char[] text = input.toCharArray();

for(String slang : slangList) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

slangList가 null일 때 NPE 가능성.

현재 호출부(WordService)는 빈 리스트로 초기화하므로 안전하지만, 공개 정적 메서드인 만큼 방어적으로 null 가드를 추가해두면 향후 오용을 예방할 수 있습니다.

🛡️ 제안
-        if(input == null || input.isBlank()) return false;
+        if(input == null || input.isBlank() || slangList == null) return false;
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/ject/vs/util/SlangFilter.java` at line 44, SlangFilter
currently iterates slangList without a null guard; add a defensive null-check at
the start of the public method in SlangFilter that uses the slangList (e.g., if
(slangList == null || slangList.isEmpty()) return <no-op>), so the method treats
a null list as empty and returns the input/result unchanged (or false) instead
of throwing NPE; update the method that contains the for(String slang :
slangList) loop to return early when slangList is null.

@@ -0,0 +1,2141 @@
가슴빨아

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

첫 줄에 BOM(U+FEFF)이 포함되어 첫 금칙어가 무력화됩니다.

파일 선두에 BOM이 있어 첫 항목이 "\uFEFF가슴빨아"로 로드됩니다. WordService.loadWordsString::trim은 U+0020 이하 문자만 제거하므로 BOM은 제거되지 않고, 결과적으로 첫 번째 금칙어가 정상적으로 매칭되지 않습니다. 파일을 BOM 없는 UTF-8로 저장하거나, 로딩 시 선두 BOM을 제거하도록 처리해 주세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/resources/data/slang.txt` at line 1, The first word contains a
leading BOM (U+FEFF) so WordService.loadWords currently yields "\uFEFF..." and
String::trim doesn't remove it; update loadWords to strip a leading BOM when
reading lines (e.g., remove '\uFEFF' or use Character.isWhitespace check for
U+FEFF) or ensure the file is saved as BOM-free UTF-8; specifically modify
WordService.loadWords to call something like line = line.replaceFirst("^\uFEFF",
"") (or equivalent) before trimming and adding to the word list so the first
forbidden word matches correctly.

Junhyukkkk and others added 20 commits June 5, 2026 01:07
  - VoteCommandService에서 ImageService 의존성을 Optional<ImageService>로 변경
  - S3가 비활성화된 테스트 환경에서도 애플리케이션 컨텍스트가 정상 로드되도록 수정
  - createWithImages 메서드에서 ImageService 없을 시 명확한 예외 메시지 제공
Junhyukkkk and others added 10 commits June 5, 2026 01:07
  - findRandomExcluding: excludeIds 제외하고 랜덤 조회
  - findRandom: 첫 조회용 랜덤 쿼리
  - countOngoing: 진행 중 투표 개수 조회
  - getNextRandom 메서드 시그니처 정의
  - ImmersiveNextResult record 추가
  - excludeIds 제외하고 랜덤 투표 조회
  - 기존 toFeedItem 메서드 재사용
  - imageUrl null 시 thumbnailUrl로 폴백 처리
  - ImmersiveNextRequest: excludeIds, size 파라미터
  - ImmersiveNextResponse: 기존 피드 응답 구조와 동일
  - 무한 순환: 모든 투표 소진 시 빈 배열 반환
  - imageUrl 있으면 그대로 반환
  - imageUrl null이면 thumbnailUrl로 폴백
Order GET /api/chats results by lastMessageAt (newest first).
Chats without messages are placed last.
Resolve chat message senderVoteOption from current participation only.
Users who canceled their vote no longer expose A/B on past messages.
@KII1ua

KII1ua commented Jun 4, 2026

Copy link
Copy Markdown
Member Author

빌드 시작

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

빌드 성공
배포 준비 완료!

@github-actions

github-actions Bot commented Jun 4, 2026

Copy link
Copy Markdown

빌드 성공
배포 준비 완료!

@KII1ua KII1ua merged commit 48ba1a9 into develop Jun 4, 2026
2 of 3 checks passed
@github-actions github-actions Bot deleted the feature/slangcheck branch June 4, 2026 16:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants